# -*- coding: utf-8 -*-

"""
@Datetime: 2018/12/30
@Author: Zhang Yafei
"""
"""创建类的两种方式"""


class Obj(object):
    x = 123

    def func(self):
        return 666


Obj1 = type('Obj1',(object,),{'x':123,'func':lambda self:666})

obj = Obj()
obj1 = Obj1()

print(obj.x, obj.func())
print(obj1.x,obj1.func())

"""2.自定义type"""


class MyType(type):
    pass


class Obj(object, metaclass=MyType):
    x = 123

    def func(self):
        return 666

Obj2 = MyType('Obj2',(object,),{'x':123,'func': lambda self:666})

# 注意：metaclass的作用是制定当前类由谁创建， 默认是由type创建

"""3.metaclass"""


class MyType(type):
    def __init__(self, *args, **kwargs):
        print('MyType的__init__')
        super(MyType, self).__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        print('MyType的__call__')
        obj3 = cls.__new__(cls)
        cls.__init__(obj3)
        return obj


class Obj3(object, metaclass=MyType):
    x = 123

    def __init__(self):
        print('Obj3的__init__')

    def __new__(cls, *args, **kwargs):
        print('Obj3的__new__')
        return object.__new__(cls)

    def func(self):
        return 666


# print(Obj3)     # MyType的__init__     <class '__main__.Obj3'>
obj3 = Obj3()   # MyType的__init__  MyType的__call__      Obj3的__new__      Obj3的__init__
# obj3 = Obj3()
# Obj3是类
# Obj3是MyType的一个对象
"""
1. 创建类时,先执行metaclass(默认为type)的__init__方法
2. 类在实例化时, 执行metaclass(默认为type)的__call__方法，__call__方法的返回值就是实例化的对象
    __call__内部调用：
        - 类.__new__方法：创建对象
        _ 类.__init__方法：对象的初始化
"""


class MyType(type):
    def __init__(self, *args, **kwargs):
        print('mytype__init__')
        super(MyType, self).__init__(*args,**kwargs)


# class Base(object, metaclass=MyType):
#     pass

# class Obj4(Base):
#     pass

def with_metaclass(arg):
    Base = MyType('Base',(arg,),{})
    # class Base(arg, metaclass=MyType):
    #   pass
    return Base


class Obj4(with_metaclass(object)):
    pass
